package pri.zxx.webdemo.controllers;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.utility.RandomString;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.assertj.core.util.Files;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pri.zxx.webdemo.utils.ZipUtils;
import pri.zxx.webdemo.utils.poi.ExportBaseService;
import pri.zxx.webdemo.utils.poi.TestEntity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Twilight
 * @desc
 * @createTime 2020-05-30-22:30
 */
@RestController
@Tag(name =  "LEARN_DEMO-文件导出接口")
@RequestMapping(value = "/files")
@Slf4j
public class PoiExportController {

	public String deal(String name, TestEntity testEntity) {
		if (name.equalsIgnoreCase("phone")) {
			return testEntity.getName();
		}
		if (name.equalsIgnoreCase("address")) {
			return "ok";
		}
		if ("wahaha".equalsIgnoreCase(name)) {
			return "testasdasdsa";
		}
		return null;
	}

	@GetMapping(value = "/out")
	public void export(HttpServletResponse response, Integer rows) throws Exception {
		List<TestEntity> zxxs = Stream.generate(() -> new TestEntity("zxx", UUID.randomUUID().toString(), new RandomString(4).nextString(), "1234124543534", "1")).limit((rows == null ? 100 : rows)).collect(Collectors.toList());
		LinkedHashMap<String, String> map = new LinkedHashMap<>();
		map.put("Name", "名称");
		map.put("Key", "关键词");
		map.put("Password", "密码");
		map.put("Phone", "手机");
		map.put("Address", "地址");
		map.put("wahaha", "附加");

		File temporaryFolder = Files.newTemporaryFolder();
		String absolutePath = temporaryFolder.getAbsolutePath();


		int splitSize = 20000;
		//计算分割后的大小
		int maxSize = (zxxs.size() + splitSize - 1) / splitSize;


		Map<String, List<TestEntity>> collect = Stream.iterate(0, n -> n + 1).limit(maxSize).parallel().map(a -> zxxs.parallelStream().skip(a * splitSize).limit(splitSize).collect(Collectors.toList())).filter(bs -> !bs.isEmpty()).collect(Collectors.toMap(testEntities -> UUID.randomUUID().toString(), t -> t));

		List<Thread> threads = new ArrayList<>();

		collect.forEach((s, testEntities) -> {
			Thread thread = new Thread(() -> {
				FileOutputStream outputStream = null;
				try {
					SXSSFWorkbook test = new ExportBaseService<TestEntity>("test").titleAndSecond(" -- 导出标题", map).contents(testEntities, map, this::deal).getWorkbook();
					outputStream = new FileOutputStream(Files.newFile(absolutePath + "/" + s + ".xlsx"));
					test.write(outputStream);
				} catch (IOException e) {
					log.error("生成excel 异常 {}", e.getMessage());
				} finally {
					try {
						if (outputStream != null) {
							outputStream.flush();
							outputStream.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}, "wahaha" + s);
			threads.add(thread);
		});

		//开始分割
		int pageSize = 40;

		int totalPage = (threads.size() + pageSize - 1) / pageSize;
		List<Integer> threadsGroup = Stream.iterate(1, integer -> integer + 1).limit(totalPage).collect(Collectors.toList());
		List<Thread> collect1;
		for (Integer page : threadsGroup) {
			collect1 = threads.stream().skip((page - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
			collect1.forEach(thread -> thread.start());
			while (!collect1.stream().allMatch(thread -> !thread.isAlive())) {

			}
		}

		response.setContentType("application/octet-stream");
		response.setHeader("Cache-Control", "no-store");
		response.setHeader("Content-Disposition", "attachment;filename=" + new String("ok.zip".getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
		ZipUtils.toZip(absolutePath, response.getOutputStream(), false, true);
		response.flushBuffer();
	}

}
